package com.googlecode.jawb.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.lang.reflect.Field;

import org.junit.Before;
import org.junit.Test;

import com.googlecode.jawb.AnnotationParser;
import com.googlecode.jawb.BinaryType;
import com.googlecode.jawb.clues.SetArray;
import com.googlecode.jawb.clues.SetCondBigger;
import com.googlecode.jawb.clues.SetCondEqual;
import com.googlecode.jawb.clues.SetCondLesser;
import com.googlecode.jawb.clues.SetCondNotEqual;
import com.googlecode.jawb.clues.SetCondition;
import com.googlecode.jawb.clues.SetIgnored;
import com.googlecode.jawb.clues.SetType;

@SuppressWarnings("unused")
public class Parser {
	private int constant1 = 5;
	private int constant2 = 10;
	private int constant3 = 15;
	private int constant4 = 20;

	@SetIgnored()
	private int constantX;
	
	@SetType(type = BinaryType.UINT_8)
	private int value1;
	
	@SetType(type = BinaryType.UINT_8)
	@SetArray(staticLength = 3)
	private int[] value2;
	
	@SetType(type = BinaryType.UINT_8)
	@SetArray(dynamicLength = "constant1")
	private int[] value3;
	
	@SetType(type = BinaryType.UINT_8)
	@SetArray(dynamicLength = "doesntExists")
	private int[] value4;
	
	@SetType(type = BinaryType.UINT_8)
	@SetCondEqual(fieldName = "constant1", value = 5)
	private int cond1;
	
	@SetType(type = BinaryType.UINT_8)
	@SetArray(staticLength = 3)
	@SetCondEqual(fieldName = "constant1", value = 5)
	private int[] cond2;
	
	@SetType(type = BinaryType.UINT_8)
	@SetCondNotEqual(fieldName = "constant2", value = 10)
	private int cond3;
	
	@SetType(type = BinaryType.UINT_8)
	@SetCondNotEqual(fieldName = "constant2", value = 11)	
	private int cond4;
	
	@SetType(type = BinaryType.UINT_8)
	@SetCondBigger(fieldName = "constant3", value = 14)
	private int cond5;
	
	@SetType(type = BinaryType.UINT_8)
	@SetCondLesser(fieldName = "constant4", value = 21)
	private int cond6;
	
	@SetType(type = BinaryType.OBJECT)
	private Object object1;
	
	@SetType(type = BinaryType.OBJECT)
	@SetArray(staticLength = 10)
	private Object[] object2;
	
	@SetType(type = BinaryType.UINT_8)
	@SetCondition(methodName = "getTrue")
	private short complexCond1;

	@SetType(type = BinaryType.UINT_8)
	@SetCondition(methodName = "getFalse")
	private short complexCond2;
	
	private AnnotationParser parser = null;
	
	@Before()
	public void init() {
		this.parser = new AnnotationParser(this);
	}
	
	protected Field getField(String name) {
		try {
			return this.getClass().getDeclaredField(name);
		} catch (Exception e) {
			throw new RuntimeException();
		}
	}
	
	private boolean getTrue() {
		return true;
	}
	
	private boolean getFalse() {
		return false;
	}
	
	@Test()
	public void isToSet() {
		this.parser.setField(this.getField("constant1"));		assertFalse(this.parser.isToSet());
		this.parser.setField(this.getField("constantX"));		assertFalse(this.parser.isToSet());
		this.parser.setField(this.getField("value1"));			assertTrue(this.parser.isToSet());
		this.parser.setField(this.getField("value2"));			assertTrue(this.parser.isToSet());
		this.parser.setField(this.getField("value3"));			assertTrue(this.parser.isToSet());
		this.parser.setField(this.getField("cond1"));			assertTrue(this.parser.isToSet());
		this.parser.setField(this.getField("cond2"));			assertTrue(this.parser.isToSet());
		this.parser.setField(this.getField("cond3"));			assertFalse(this.parser.isToSet());
		this.parser.setField(this.getField("cond4"));			assertTrue(this.parser.isToSet());
		this.parser.setField(this.getField("cond5"));			assertTrue(this.parser.isToSet());
		this.parser.setField(this.getField("cond6"));			assertTrue(this.parser.isToSet());
	}
	
	@Test()
	public void isValue() {
		this.parser.setField(this.getField("value1"));			assertTrue(this.parser.isValue());
		this.parser.setField(this.getField("value2"));			assertFalse(this.parser.isValue());
	}
	
	@Test()
	public void isArray() {
		this.parser.setField(this.getField("value1"));			assertFalse(this.parser.isArray());
		this.parser.setField(this.getField("value2"));			assertTrue(this.parser.isArray());
	}
	
	@Test()
	public void isPrimitiveValue() {
		this.parser.setField(this.getField("value1"));			assertTrue(this.parser.isPrimitiveValue());
		this.parser.setField(this.getField("object1"));			assertFalse(this.parser.isPrimitiveValue());
		this.parser.setField(this.getField("object2"));			assertFalse(this.parser.isPrimitiveValue());
	}
	
	@Test()
	public void isObject() {
		this.parser.setField(this.getField("value1"));			assertFalse(this.parser.isObject());
		this.parser.setField(this.getField("object1"));			assertTrue(this.parser.isObject());
		this.parser.setField(this.getField("object2"));			assertTrue(this.parser.isObject());
	}
	
	@Test()
	public void getArrayLength() {
		this.parser.setField(this.getField("value2"));			assertEquals(this.parser.getArrayLength(), 3);
		this.parser.setField(this.getField("value3"));			assertEquals(this.parser.getArrayLength(), 5);
	}
	
	@Test()
	public void complexConds() {
		this.parser.setField(this.getField("complexCond1"));	assertTrue(this.parser.isToSet());
		this.parser.setField(this.getField("complexCond2"));	assertFalse(this.parser.isToSet());
	}
}
